using UnityEngine;
using System.Collections;

public class CameraControl : StateBehaviour<CameraControl>, ICommand
{

 	#region Attributes

    public Camera mainCamera = null;
    public Vector3 distance = Vector3.zero;
	public Vector3 zoneViewDistance = Vector3.zero;
	public Vector3 camRotation = Vector3.zero;
	public Vector3 overviewPos = Vector3.zero;
	public Vector3 actionViewPos = Vector3.zero;
	public GameObject overviewPoint = null;
    
	public float fullSpeed = 0.0f;
	public float offset = 0.0f;

    [HideInInspector]
	public bool actionView = false;
    [HideInInspector]
    public bool notifyActionViewCompleted = false;
    [HideInInspector]
	public bool zoomOut = false;
	
	[HideInInspector]
	public Vector3 currentTargetDistance;
	[HideInInspector]
	public Vector3 moveDistance;
	[HideInInspector]
    public float speed = 0.0f;
	[HideInInspector]
    public Vector3 targetDistance;
    [HideInInspector]
    public GameObject actionViewPoint = null;
    [HideInInspector]
    public IReceiver receiver;
	
	public ViewDelimiter viewDelimiter;
	
    #endregion

    #region Props
    public ViewDelimiter ViewDelimiter 
    {
		get { return this.viewDelimiter; }
	}
    #endregion

    #region Methods
    private void Init(State<CameraControl> state)
    {
        this.State = state;
	}
	
	private void ReadInput()
	{
        if (GameControl.isInputEnabled)
		    if (Input.GetKey("space") && !this.actionView && !this.zoomOut)
		    {
			    Init(CameraZoomOutState.Instance);
		    }
	}
	
    public Vector3 CalculateMoveDistance(Vector3 currentTargetDistance)
	{	
		Vector3 moveDistance = currentTargetDistance - this.mainCamera.transform.position;
		
        return moveDistance;
    }
	
	public void SetCameraZoneViewDistance(Vector3 zViewDist)
	{
		this.zoneViewDistance = zViewDist;
	}
	
	public void SetCameraActionViewPos(GameObject actionVP)
	{
		this.actionViewPos = actionVP.transform.position;
	}
	
	public void ChangeCameraStateTo(string stateName)
	{
		if (stateName == StateConstants.CAMERA_ACTION_VIEW_STATE)
			Init(CameraActionViewState.Instance);
		
		if (stateName == StateConstants.CAMERA_ZONE_VIEW_STATE)
			Init(CameraZoneViewState.Instance);
		
		if (stateName == StateConstants.CAMERA_FOLLOW_STATE)
			Init(CameraFollowState.Instance);
	}
	

    public void Move(Vector3 moveDistance, Vector3 currentTargetDistance)
    {
        

        if (currentTargetDistance.magnitude > offset)
        {
            moveDistance = PhysxHelper.GetUniformRectilinearMotion(moveDistance, this.fullSpeed);
            this.mainCamera.transform.Translate(moveDistance, Space.World);
            
        }
        
    }
    #endregion

    #region Unity Methods
	
	void Start()
    {
        if (this.mainCamera == null)
            this.mainCamera = Camera.main;
		if (this.overviewPoint == null)
			this.actionViewPoint = GameObject.Find("ActionPoint");
		if (this.overviewPoint == null)
			this.overviewPoint = GameObject.Find("OverviewPoint");
		
		this.Init(CameraFollowState.Instance);
		
		viewDelimiter = gameObject.GetComponent<ViewDelimiter>();
		
        this.mainCamera.transform.position = this.transform.position + this.distance;
		this.mainCamera.transform.eulerAngles = camRotation;
		
		this.overviewPos = this.overviewPoint.transform.position;
		
    }

	
    #endregion

    #region StateBehaviour

    public override void OnUpdate()
    {
		ReadInput();	
		
    }
	
    public override CameraControl GetBehaviuor()
    {
        return this;
    }

    #endregion

    #region ICommand
    public void Execute(IReceiver _receiver, params object[] args)
    {
        this.receiver = _receiver;

        try
        {
			// Change State and go to position
            Transform point = args[0] as Transform;
			actionViewPos = point.position;
			ChangeCameraStateTo(StateConstants.CAMERA_ACTION_VIEW_STATE);     
        }
        catch (System.Exception e)
        {
            Debug.LogError(e.StackTrace);
            receiver.Action(); // Prevent game crash on error
        }
    }
    #endregion
}